﻿using Admin.NET.Application.Entity;
using Admin.NET.Application.Enums;
using Admin.NET.Core.Service;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.Http;

namespace Admin.NET.Application;

/// <summary>
/// 从机模板服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class DeviceSlaveTemplateService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<DeviceSlaveTemplate> _deviceSlaveTemplateRep;
    private readonly SysFileService _sysFileService;

    public DeviceSlaveTemplateService(SqlSugarRepository<DeviceSlaveTemplate> deviceSlaveTemplateRep, SysFileService sysFileService)
    {
        _deviceSlaveTemplateRep = deviceSlaveTemplateRep;
        this._sysFileService = sysFileService;
    }

    /// <summary>
    /// 分页查询从机模板
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询从机模板")]
    public async Task<SqlSugarPagedList<DeviceSlaveTemplateOutput>> Page(PageDeviceSlaveTemplateInput input)
    {
        input.SearchKey = input.SearchKey?.Trim();
        var query = _deviceSlaveTemplateRep.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
                u.SlaveName.Contains(input.SearchKey)
            )
            .WhereIF(!string.IsNullOrWhiteSpace(input.SlaveName), u => u.SlaveName.Contains(input.SlaveName.Trim()))
            .WhereIF(input.DeviceTemplateInfoId >= 0, u => u.DeviceTemplateInfoId == input.DeviceTemplateInfoId)
        
            //处理外键和TreeSelector相关字段的连接
            .LeftJoin<DeviceTemplateInfo>((u, devicetemplateinfoid) => u.DeviceTemplateInfoId == devicetemplateinfoid.Id)
            .Select((u, devicetemplateinfoid) => new DeviceSlaveTemplateOutput
            {
                Id = u.Id,
                SlaveName = u.SlaveName,
                RelProductId = u.RelProductId,
                DeviceTemplateInfoId = u.DeviceTemplateInfoId,
                DeviceTemplateInfoIdTemplateName = devicetemplateinfoid.TemplateName,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                IsDelete = u.IsDelete,
            });
        return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
    }

    /// <summary>
    /// 增加从机模板
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    [DisplayName("增加从机模板")]
    public async Task<long> Add(AddDeviceSlaveTemplateInput input)
    {
        var entity = input.Adapt<DeviceSlaveTemplate>();
        await _deviceSlaveTemplateRep.InsertAsync(entity);
        return entity.Id;
    }

    /// <summary>
    /// 删除从机模板
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除从机模板")]
    public async Task Delete(DeleteDeviceSlaveTemplateInput input)
    {
        var entity = await _deviceSlaveTemplateRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        //删除的时候判断模板有没有被设备关联
        var isAssociated = await _deviceSlaveTemplateRep.Context.Queryable<DeviceInfo>()
            .AnyAsync(drs => drs.DeviceTemplateInfoId == entity.Id);
        if (isAssociated)
        {
            throw Oops.Oh(DeviceErrorCodeEnum.TemplateHasBinUsed);
        }
        //删除的时候判断模板有没有被设备关联


        //获取从机底下所有的point并删除

        //await _deviceSlaveTemplateRep.FakeDeleteAsync(entity);   //假删除
        // 获取从机模板下所有的点信息
        var points = await _deviceSlaveTemplateRep.Context.Queryable<DeviceSlaveTemplatePoints>()
            .Where(p => p.DeviceSlaveTemplateId == entity.Id)
            .ToListAsync();

        // 删除所有点信息
        if (points.Any())
        {
            await _deviceSlaveTemplateRep.Context.Deleteable<DeviceSlaveTemplatePoints>(points).ExecuteCommandAsync();
        }

        //删除 对应的devicerelSlave
        var deviceRelSlaves = await _deviceSlaveTemplateRep.Context.Queryable<DeviceRelSlave>()
            .Where(drs => drs.DeviceSlaveTemplateId == entity.Id)
            .ToListAsync();

        if (deviceRelSlaves.Any())
        {
            await _deviceSlaveTemplateRep.Context.Deleteable<DeviceRelSlave>(deviceRelSlaves).ExecuteCommandAsync();
        }


        var re = await _deviceSlaveTemplateRep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 更新从机模板
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新从机模板")]
    public async Task Update(UpdateDeviceSlaveTemplateInput input)
    {
        var entity = input.Adapt<DeviceSlaveTemplate>();
        await _deviceSlaveTemplateRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }

    /// <summary>
    /// 获取从机模板
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取从机模板")]
    public async Task<DeviceSlaveTemplate> Detail([FromQuery] QueryByIdDeviceSlaveTemplateInput input)
    {
        return await _deviceSlaveTemplateRep.GetFirstAsync(u => u.Id == input.Id);
    }

    /// <summary>
    /// 获取从机模板列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取从机模板列表")]
    public async Task<List<DeviceSlaveTemplateOutput>> List([FromQuery] PageDeviceSlaveTemplateInput input)
    {
        return await _deviceSlaveTemplateRep.AsQueryable().Select<DeviceSlaveTemplateOutput>().ToListAsync();
    }

    /// <summary>
    /// 获取设备模板Id列表
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "DeviceTemplateInfoDeviceTemplateInfoIdDropdown"), HttpGet]
    [DisplayName("获取设备模板Id列表")]
    public async Task<dynamic> DeviceTemplateInfoDeviceTemplateInfoIdDropdown()
    {
        return await _deviceSlaveTemplateRep.Context.Queryable<DeviceTemplateInfo>()
                .Select(u => new
                {
                    Label = u.TemplateName,
                    Value = u.Id
                }
                ).ToListAsync();
    }
}